// VBlock.h
// This file defines class VBlock
#ifndef VBLOCK_H
#define VBLOCK_H

#include "crossbit/VInst.h"
#include "crossbit/VBlockBuilder.h"
#include <vector>
#include <iterator>
#include <iostream>
#include <iomanip>

namespace crossbit {

    // For the beginning, VBlock is just an wrap class for vector<VInst *>
    class VBlock {
        //								friend void VBlockBuilder::add(VInst *inst);
        //	
		//	friend VBlock* VBlockBuilder::wrapUp(XTMemAddr pc);

		// Add BY zhunan 2010-3-11
		private:
			int VBlock_ID;//identify the VBlocks
			int inhotpath;//to designate if the block is hot
			long long Run_Count;//caculate the run times of a block

			//Add By zhunan 2010-3-15
			int in_CFG;
			int is_loop_head;
			int in_loop_path;
			int loop_level;//meanless until is_loop_head==1;
			
			//added by zhunan 4-13
			int ld_count;
			int st_count;

        public:
            typedef std::vector<VInst *>::iterator				vb_iterator;
            typedef std::vector<VInst *>::const_iterator			vb_const_iterator;
            typedef std::vector<VInst *>::reverse_iterator		vb_reverse_iterator;
            typedef std::vector<VInst *>::const_reverse_iterator	vb_const_reverse_iterator;

            VBlock(XTMemAddr enter_spc) 
                : vb_enter_spc(enter_spc) 
			{ 
				VBlock_ID=0;
				vb_next_spc = 0;
				Run_Count=0;
				inhotpath=0;
				in_CFG=-1;
				is_loop_head=0;
				in_loop_path=0;
				loop_level=0;
				ld_count = 0;
				st_count = 0;
			}

            // Added by Zhang Yichao for CFG
            VBlock(XTMemAddr enter_spc, XTMemAddr next_spc)
                : vb_enter_spc(enter_spc), vb_next_spc(next_spc) {}

            ~VBlock() { clear(); }
			void Add_Run_Count()
			{
				++(this->Run_Count);
		//		return 
			}
			long long Get_Run_Count(){ return this->Run_Count;}
			int Get_VBlock_ID()
			{
				return this->VBlock_ID;
			}
			void Set_LD_count(int i)
			{
				ld_count=i;
			}
			int Get_LD_count()
			{
				return ld_count;
			}

			void Set_ST_count(int i)
			{
				st_count=i;
			}

			int Get_ST_count()
			{
				return st_count;
			}

			void Set_VBlock_ID(int id)
			{
				this->VBlock_ID=id;
			}
			void Set_In_CFG(int position)
			{
				this->in_CFG=position;
			}
			int Get_In_CFG()
			{
				return in_CFG;
			}

			void Set_In_loop()
			{
				this->in_loop_path=1;

			}
			int Get_In_loop()
			{
				return this->in_loop_path;
			}

			void Set_is_loop_head(int level)
			{
				this->is_loop_head=level;
			}
			int Get_loop_head()
			{
				return this->is_loop_head;
			}

			void Add_loop_level()
			{
				this->loop_level++;
			}
			
			
            void push_back(VInst * const inst) { vb_ilist.push_back(inst); }

            vb_iterator insert(vb_iterator it, VInst * const vinst) 
            { return vb_ilist.insert(it, vinst); }

            vb_iterator erase(vb_iterator it) 
            { return vb_ilist.erase(it); }

            XTUint32 size() const { return vb_ilist.size(); }

            // Added by zhangyichao
            VInst *getVInst(XTInt32 i) { return vb_ilist[i]; }

            bool empty() const { return vb_ilist.empty(); }

            void setVbIlist(XTInt32 index, VInst *inst)
            {
                if( index >= 0 && index <= vb_ilist.size() )
                    vb_ilist[index] = inst;
                else
                    return;
            }

            // instruction iterator methods
            vb_iterator		    		begin()			{ return vb_ilist.begin(); }
            vb_const_iterator			begin()	const	{ return vb_ilist.begin(); }
            vb_iterator		    		end()		    { return vb_ilist.end(); }
            vb_const_iterator			end()	const	{ return vb_ilist.end(); }
            vb_reverse_iterator			rbegin()		{ return vb_ilist.rbegin(); }
            vb_const_reverse_iterator	rbegin()const	{ return vb_ilist.rbegin(); }
            vb_reverse_iterator	    	rend()			{ return vb_ilist.rend(); }
            vb_const_reverse_iterator  	rend()	const	{ return vb_ilist.rend(); }

            void clear() 
            {
                for (vb_iterator it = vb_ilist.begin(); it != vb_ilist.end(); ++it)
                    delete (*it);
                vb_ilist.clear();
            }

            XTMemAddr enterSPC()	const	{ return vb_enter_spc; }
            XTMemAddr nextSPC()	const	{ return vb_next_spc; }

            void setVbNextSpc( XTMemAddr spc )
            {
                vb_next_spc = spc;
                return;
            }

            void print(std::ostream &os) {
                vb_iterator I = begin(),
                            E = end();

                for (int i = 0; I != E; ++I, ++i) {
                    os << std::dec << std::setw(3) << std::right << i << ": " << **I << std::endl;
                }
            }
            void setFlagsCount(int count)
            {
                flagsCount = count;
            }

            void setTotalCount(int count)
            {
                totalCount = count;
            }

            int getFlagsCount()
            {
                return flagsCount;
            }

            int getTotalCount()
            {
                return totalCount;
            }
        private:
            XTMemAddr vb_enter_spc;
            XTMemAddr vb_next_spc;
            std::vector<VInst *> vb_ilist;
		public:
           //  forbid copy constructor
           	VBlock(const VBlock &  s_vb)
			{
				this->VBlock_ID = s_vb.VBlock_ID; 
			}


            // forbid copy assignment
          	VBlock& operator=(const VBlock &) 
            { return *this; }     
		private:
            int flagsCount;
            int totalCount;
    };

}

#endif
